using _ReplaceString_.RSConfigs;
using _ReplaceString_.UI.Styles;
using RSCore;
using Terraria.ModLoader.UI;

namespace _ReplaceString_.UI.Elements;

public class PackageGroup : UIBase
{
	private List<PackageID> _enabled = new();

	private string _mod;

	private LeftPanel _leftPanel;

	private IEnumerable<PackageID> SearchPackage()
	{
		var dir = Directory.CreateDirectory(Path.Combine(ModHelper.PackagePath)).CreateSubdirectory(_mod);

		foreach (var file in ReplaceString.Instance.File.Where(s => s.Name.StartsWith($@"Packages\{_mod}\")))
		{
			yield return new PackageID(_mod, Path.GetFileNameWithoutExtension(file.Name), PackageType.BuiltIn);
		}

		foreach (var file in dir.EnumerateFiles("*.json", SearchOption.TopDirectoryOnly))
		{
			yield return new PackageID(_mod, Path.GetFileNameWithoutExtension(file.Name), PackageType.Test);
		}
	}

	private IEnumerable<(PackageID, int)> OrderPackage(IEnumerable<PackageID> packages)
	{
		var enabled = LocalConfig.GetPackages(_mod);
		return packages.Zip(packages.Select(p => enabled.IndexOf(p))).OrderBy(p =>
		{
			return p.Second == -1 ? int.MaxValue : p.Second;
		}).ThenBy(p => p.First.Name);
	}

	public PackageGroup(string mod, LeftPanel leftPanel)
	{
		_mod = mod;
		_leftPanel = leftPanel;
		AddStyle(UIScroll.Window);
		ResetChildren();
	}

	private void ResetChildren()
	{
		RemoveAllChildren();
		_enabled.Clear();
		var scroll = new UIBase()
		{
			ExtraColor = Color.Gray,
			PaddingLeft = 6,
			PaddingRight = 6,
		};
		scroll.AddStyle(UIScroll.Vertical, UILayout.Vertical, UISize.Fill, UISize.FlexibleHeight);
		Append(scroll);
		bool hasBackground = true;
		foreach (var (id, index) in OrderPackage(SearchPackage()))
		{
			bool enable = index != -1;
			if (enable)
			{
				_enabled.Add(id);
			}

			var group = new UIBase
			{
				BackgroundColor = hasBackground ? UICommon.DefaultUIBlueMouseOver : Color.Transparent,
			};
			hasBackground = !hasBackground;
			group.AddStyle(UISize.Fill, UISize.FixedHeight(50), UILayout.Horizontal, UIBackground.Rect);
			scroll.Append(group);

			var child = new PackageElement(id, enable, _leftPanel);
			child.AddStyle(UIRender.Click);
			child.OnLeftClick += (_, _) => ClickPackage(id);
			group.Append(child);

			if (!enable)
			{
				continue;
			}

			var asset = Main.Assets.Request<Texture2D>("Images/UI/TexturePackButtons", ReLogic.Content.AssetRequestMode.ImmediateLoad);
			var upArrow = new ImageElement(asset.Value)
			{
				SourceRectange = new Rectangle(0, 0, 32, 32),
			};
			upArrow.AddStyle(UIRender.Click, UISize.FixedHeight(50), UISize.FixedWidth(50));
			upArrow.OnLeftClick += (_, _) => ClickUpArrow(id);
			group.Append(upArrow);

			var downArrow = new ImageElement(asset.Value)
			{
				SourceRectange = new Rectangle(32, 0, 32, 32),
			};
			downArrow.AddStyle(UIRender.Click, UISize.FixedHeight(50), UISize.FixedWidth(50));
			downArrow.OnLeftClick += (_, _) => ClickDownArrow(id);
			group.Append(downArrow);
		}
		Recalculate();
	}

	private void ClickPackage(PackageID id)
	{
		if (_enabled.Contains(id))
		{
			_enabled.Remove(id);
		}
		else
		{
			_enabled.Add(id);
		}
		LocalConfig.SetPackages(_mod, _enabled);
		ResetChildren();
		RSConfig.ShouldReload = true;
	}

	private void ClickDownArrow(PackageID id)
	{
		int index = _enabled.IndexOf(id);
		if (index >= 0 && index < _enabled.Count - 1)
		{
			(_enabled[index], _enabled[index + 1]) = (_enabled[index + 1], _enabled[index]);
			LocalConfig.SetPackages(_mod, _enabled);
			ResetChildren();
			RSConfig.ShouldReload = true;
		}
	}

	private void ClickUpArrow(PackageID id)
	{
		int index = _enabled.IndexOf(id);
		if (index > 0)
		{
			(_enabled[index], _enabled[index - 1]) = (_enabled[index - 1], _enabled[index]);
			LocalConfig.SetPackages(_mod, _enabled);
			ResetChildren();
			RSConfig.ShouldReload = true;
		}
	}
}